﻿/**
* @description  Abstract base class to handle displaying of loaded media.
*/
package com.moke.media.displays {

	import flash.display.Sprite;
	import flash.display.DisplayObject;
	import flash.geom.Rectangle;
	
	import com.moke.media.events.MediaEvent;
	import com.moke.media.controllers.MediaController;

	public class MediaDisplay extends Sprite {
	
		private var _mediaController:MediaController;
		private var _scaleMode:String = ScaleModes.SHOW_ALL;
		private var _displayWidth:Number;
		private var _displayHeight:Number;
		protected var _mediaClip:DisplayObject;
		protected var _mediaWidth:Number;
		protected var _mediaHeight:Number;
	
		/**
		* @description  Constructor.
		*/
		public function MediaDisplay() {
			init();
		}
	
		/**
		* @description	Initializes component properties.
		*/	
		private function init():void {
			createMediaClip();
		}

		/**
		* @description	Scales media proportionally to fill component space.
		*/	
		private function scaleMedia():void {
			var pRatio:Number;
			if (_displayWidth > _displayHeight) {
				pRatio = _displayHeight/_mediaHeight;
				if (_mediaHeight < _mediaWidth && _mediaWidth*pRatio > _displayWidth) {
					pRatio = _displayWidth/_mediaWidth;
				}
			} else {
				pRatio = _displayWidth/_mediaWidth;
				if (_mediaWidth < _mediaHeight && _mediaHeight*pRatio > _displayHeight) {
					pRatio = _displayHeight/_mediaHeight;
				}
			}
			_mediaClip.width = _mediaWidth*pRatio;
			_mediaClip.height = _mediaHeight*pRatio;
			positionMedia();
		}

		/**
		* @description	Positions media within the component based on the alignment settings.
		*/	
		private function positionMedia():void {
			_mediaClip.x = (_displayWidth - _mediaClip.width)/2;
			_mediaClip.y = (_displayHeight - _mediaClip.height)/2;
		}

		/**
		* @description	Scales media within the component based on the scale mode settings.
		*/	
		protected function sizeMedia():void {
			_mediaClip.scrollRect = _mediaClip.getRect(_mediaClip);
			switch (_scaleMode) {
				case ScaleModes.EXACT_FIT:
					_mediaClip.width = _displayWidth;
					_mediaClip.height = _displayHeight;
					break;
				case ScaleModes.NO_SCALE:
					positionMedia();
					if (_mediaWidth > _displayWidth || _mediaHeight > _displayHeight) {
						_mediaClip.scrollRect = new Rectangle(0, 0, _displayWidth, _displayHeight);
					}
					break;
				case ScaleModes.SCALE_DOWN:
					if (_mediaWidth > _displayWidth || _mediaHeight > _displayHeight) {
						scaleMedia();
					} else {
						positionMedia();
					}
					break;
				case ScaleModes.SHOW_ALL:
					scaleMedia();
					break;
			}
		}

		/**
		* @description	Creates whatever object is necessary to load media (must be overridden by concrete classes).
		*/	
		protected function createMediaClip():void {
			if (_mediaClip != null) removeChildAt(0);
		}
	
		/**
		* @description	Sets metadata based on the information from the controller.
		*
		* @param  pEvent  Event fired by MediaController.
		*/	
		protected function setMetadata(pEvent:MediaEvent):void {
			if (pEvent.width > 0 && pEvent.height > 0) {
				_mediaWidth = pEvent.width;
				_mediaHeight = pEvent.height;
				sizeMedia();
			}
		}

		/**
		* @description	Returns a reference to the MediaController whose media is displayed.
		*
		* @returns  The MediaController with media displayed by this instance.
		*/	
		public function getController():MediaController { return _mediaController; }	

		/**
		* @description	Sets the MediaController whose media will be displayed.
		*
		* @param  pController  The MediaController with media to display.
		*/	
		public function setController(pController:MediaController):void { _mediaController = pController; }
	
		/**
		* @description	Returns the current method of scaling the media.
		*
		* @returns  A constant of ScaleModes, which determines how media will be scaled.
		*/	
		public function get scaleMode():String { return _scaleMode; }	

		/**
		* @description	Sets the method the media will be scaled.
		*
		* @param  pMode  A constant of ScaleModes, which determines how media will be scaled.
		*/	
		public function set scaleMode(pMode:String):void {
			_scaleMode = pMode;
			sizeMedia();
		}

		/**
		* @description	Returns the original width of the displayed media.
		*
		* @returns  The original width of the displayed media.
		*/	
		public function get mediaWidth():Number { return _mediaWidth; }

		/**
		* @description	Returns the original height of the displayed media.
		*
		* @returns  The original height of the displayed media.
		*/	
		public function get mediaHeight():Number { return _mediaHeight; }

		/**
		* @description	Returns the pixel width of the media display.
		*
		* @returns  The pixel width of the media display.
		*/	
		public function get displayWidth():Number { return _displayWidth; }

		/**
		* @description	Sets the pixel width of the media display.
		*
		* @param  pWidth  The pixel width of the media display.
		*/	
		public function set displayWidth(pWidth:Number):void { _displayWidth = pWidth; }

		/**
		* @description	Returns the pixel height of the media display.
		*
		* @returns  The pixel height of the media display.
		*/	
		public function get displayHeight():Number { return _displayHeight; }

		/**
		* @description	Sets the pixel height of the media display.
		*
		* @param  pWidth  The pixel height of the media display.
		*/	
		public function set displayHeight(pHeight:Number):void { _displayHeight = pHeight; }

	}
	
}